from flask import request, jsonify
from datetime import datetime, timedelta
import jwt
from app.models import User, db
from app.config import Config
from sqlalchemy.exc import IntegrityError


def generate_token(user_id):
    """
    生成JWT token
    
    Args:
        user_id: 用户ID
    
    Returns:
        JWT token字符串
    """
    # 设置token过期时间为7天
    payload = {
        'exp': datetime.utcnow() + timedelta(days=7),
        'iat': datetime.utcnow(),
        'user_id': user_id
    }
    
    # 使用密钥生成token
    token = jwt.encode(payload, Config.SECRET_KEY, algorithm='HS256')
    return token


def register():
    """
    用户注册接口
    
    Returns:
        JSON响应
    """
    try:
        # 获取请求数据
        data = request.get_json()
        
        # 验证参数
        if not all(key in data for key in ['username', 'email', 'password']):
            return jsonify({
                'code': 400,
                'message': '用户名、邮箱和密码不能为空',
                'data': None
            }), 400
        
        # 检查用户名是否已存在
        if User.query.filter_by(username=data['username']).first():
            return jsonify({
                'code': 400,
                'message': '用户名已存在',
                'data': None
            }), 400
        
        # 检查邮箱是否已存在
        if User.query.filter_by(email=data['email']).first():
            return jsonify({
                'code': 400,
                'message': '邮箱已存在',
                'data': None
            }), 400
        
        # 创建新用户
        new_user = User(
            username=data['username'],
            email=data['email'],
            nickname=data['username']  # 昵称默认为用户名
        )
        
        # 设置密码（会自动加密）
        new_user.set_password(data['password'])
        
        # 保存到数据库
        db.session.add(new_user)
        db.session.commit()
        
        # 生成token
        token = generate_token(new_user.id)
        
        # 返回成功响应
        return jsonify({
            'code': 201,
            'message': '注册成功',
            'data': {
                'token': token,
                'user': {
                    'id': new_user.id,
                    'username': new_user.username,
                    'email': new_user.email,
                    'nickname': new_user.nickname,
                    'role': new_user.role.value
                }
            }
        }), 201
        
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'code': 500,
            'message': f'注册失败: {str(e)}',
            'data': None
        }), 500


def login():
    """
    用户登录接口
    
    Returns:
        JSON响应
    """
    try:
        # 获取请求数据
        data = request.get_json()
        
        # 验证参数
        if not all(key in data for key in ['username', 'password']):
            return jsonify({
                'code': 400,
                'message': '用户名和密码不能为空',
                'data': None
            }), 400
        
        # 查询用户
        user = User.query.filter_by(username=data['username']).first()
        
        # 验证用户和密码
        if not user or not user.check_password(data['password']):
            return jsonify({
                'code': 401,
                'message': '用户名或密码错误',
                'data': None
            }), 401
        
        # 生成token
        token = generate_token(user.id)
        
        # 返回成功响应
        return jsonify({
            'code': 200,
            'message': '登录成功',
            'data': {
                'token': token,
                'user': {
                    'id': user.id,
                    'username': user.username,
                    'email': user.email,
                    'nickname': user.nickname,
                    'role': user.role.value
                }
            }
        })
        
    except Exception as e:
        return jsonify({
            'code': 500,
            'message': f'登录失败: {str(e)}',
            'data': None
        }), 500


def get_profile():
    """
    获取当前用户信息接口
    
    Returns:
        JSON响应
    """
    try:
        # 从请求上下文中获取用户ID
        user_id = request.current_user_id
        
        # 查询用户
        user = User.query.get(user_id)
        
        if not user:
            return jsonify({
                'code': 404,
                'message': '用户不存在',
                'data': None
            }), 404
        
        # 返回用户信息
        return jsonify({
            'code': 200,
            'message': '获取成功',
            'data': {
                'id': user.id,
                'username': user.username,
                'email': user.email,
                'nickname': user.nickname,
                'role': user.role.value,
                'created_at': user.created_at.isoformat() + 'Z'
            }
        })
        
    except Exception as e:
        return jsonify({
            'code': 500,
            'message': f'获取用户信息失败: {str(e)}',
            'data': None
        }), 500


def change_password():
    """
    修改密码接口
    
    Returns:
        JSON响应
    """
    try:
        # 获取请求数据
        data = request.get_json()
        
        # 验证参数
        if not all(key in data for key in ['oldPassword', 'newPassword']):
            return jsonify({
                'code': 400,
                'message': '旧密码和新密码不能为空',
                'data': None
            }), 400
        
        # 从请求上下文中获取用户ID
        user_id = request.current_user_id
        
        # 查询用户
        user = User.query.get(user_id)
        
        if not user:
            return jsonify({
                'code': 404,
                'message': '用户不存在',
                'data': None
            }), 404
        
        # 验证旧密码
        if not user.check_password(data['oldPassword']):
            return jsonify({
                'code': 400,
                'message': '旧密码错误',
                'data': None
            }), 400
        
        # 设置新密码
        user.set_password(data['newPassword'])
        
        # 保存到数据库
        db.session.commit()
        
        # 返回成功响应
        return jsonify({
            'code': 200,
            'message': '密码修改成功'
        })
        
    except Exception as e:
        db.session.rollback()
        return jsonify({
            'code': 500,
            'message': f'修改密码失败: {str(e)}',
            'data': None
        }), 500